package 每日一题;

import 我的JDK基础数据结构.HashMap.HashMap;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @description:
 * @author: 小白白
 * @create: 2021-09-26
 **/

public class No166分数到小数 {

    /**
     * 给定两个整数，分别表示分数的分子 numerator 和分母 denominator，以 字符串形式返回小数 。
     * 如果小数部分为循环小数，则将循环的部分括在括号内。
     * 如果存在多个答案，只需返回 任意一个 。
     * 对于所有给定的输入，保证 答案字符串的长度小于 104 。
     *
     * 示例 1：
     * 输入：numerator = 1, denominator = 2
     * 输出："0.5"
     * 示例 2：
     * 输入：numerator = 2, denominator = 1
     * 输出："2"
     * 示例 3：
     * 输入：numerator = 2, denominator = 3
     * 输出："0.(6)"
     * 示例 4：
     * 输入：numerator = 4, denominator = 333
     * 输出："0.(012)"
     * 示例 5：
     * 输入：numerator = 1, denominator = 5
     * 输出："0.2"
     *  
     *
     * 提示：
     * -231 <= numerator, denominator <= 231 - 1
     * denominator != 0
     */

    public String fractionToDecimal(int numerator, int denominator) {

        if (numerator == 0) {
            return "0";
        }

        StringBuilder result = new StringBuilder();

        boolean positive = true;
        if (numerator < 0 && denominator > 0) {
            positive = false;
        }
        if (numerator > 0 && denominator < 0) {
            positive = false;
        }

        long numeratorL = Math.abs(Long.valueOf(numerator));
        long denominatorL = Math.abs(Long.valueOf(denominator));

        // 得到商
        long quotient = numeratorL / denominatorL;
        result.append(quotient);

        // 得到余数
        long remainder = numeratorL % denominatorL;

        if (remainder == 0) {
            return positive ? result.toString() : "-" + result.toString();
        }

        result.append(".");

        Map<Long,Integer> map = new HashMap<>();

        StringBuilder temp = new StringBuilder();

        int cyclicIndex = -1;
        // 开始获取小数
        while (remainder != 0) {

            /**
             * 应该是将余数放进map
             * 循环标志是余数!!!
             * 那为什么余数要在第一位呢?是当前的余数不存在才能放入,不要省略第一个余数
             */
            // 如果这次的余数重复了,说明进入了循环
            if (map.containsKey(remainder)) {
                // 上次的下标
                cyclicIndex = map.get(remainder);
                break;
            }

            map.put(remainder, temp.length());

            // 将余数扩大十倍,然后求商
            remainder *= 10;

            // 得到商
            quotient = remainder / denominatorL;

            // 获取下次的余数
            remainder = remainder % denominatorL;

            // 加进小数集合
            temp.append(quotient);
        }

        // 是否为循环小数字?
        if (cyclicIndex != -1) {
            // 为有循环小数
            // 非循环小数字
            String s1 = temp.substring(0, cyclicIndex);
            // 循环小数
            String s2 = temp.substring(cyclicIndex);
            result.append(s1).append("(").append(s2).append(")");
        } else {
            result.append(temp);
        }

        return positive ? result.toString() : "-" + result.toString();
    }

    public static void main(String[] args) {
        No166分数到小数 n = new No166分数到小数();
        String result = n.fractionToDecimal(-2147483648, -1);
        System.out.println(result);
    }

}
